package com.adam.test.example;

import org.springframework.transaction.annotation.Propagation;

/**
 * 事务传播行为操作示例
 *
 * @author jiangwh
 */
public interface PropagationAddExample {

    /**
     * 清理表
     */
    void truncate();

    /**
     * 子方法1成功，子方法2成功
     * <ul>
     *     <li>主方法：不使用事务，抛出异常</li>
     *     <li>子方法1：不使用事务</li>
     *     <li>子方法2：不使用事务</li>
     * </ul>
     */
    void noEx_no_no();

    /**
     * 子方法1成功，子方法2成功
     * <ul>
     *     <li>主方法：不使用事务</li>
     *     <li>子方法1：不使用事务</li>
     *     <li>子方法2：不使用事务，抛出异常</li>
     * </ul>
     */
    void no_no_noEx();

    /**
     * 子方法1成功，子方法2成功
     * <ul>
     *     <li>主方法：不使用事务，抛出异常</li>
     *     <li>子方法1：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法2：使用{@link Propagation#REQUIRED}</li>
     * </ul>
     */
    void noEx_required_required();

    /**
     * 子方法1成功，子方法2回滚（主方法无事务，子方法的事务互相独立，不会相互影响）
     * <ul>
     *     <li>主方法：不使用事务</li>
     *     <li>子方法1：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法2：使用{@link Propagation#REQUIRED}，抛出异常</li>
     * </ul>
     */
    void no_required_requiredEx();

    /**
     * 子方法1回滚，子方法2回滚（子方法无事务，主方法调用子方法，为正常方法调用，等同于使用同一个事务）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}，抛出异常</li>
     *     <li>子方法1：不使用事务</li>
     *     <li>子方法2：不使用事务</li>
     * </ul>
     */
    void requiredEx_no_no();

    /**
     * 子方法1回滚，子方法2回滚（子方法无事务，主方法调用子方法，为正常方法调用，等同于使用同一个事务）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法1：不使用事务</li>
     *     <li>子方法2：不使用事务，抛出异常</li>
     * </ul>
     */
    void required_no_noEx();

    /**
     * 子方法1回滚，子方法2回滚（主方法存在事务，子方法加入该事务中）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}，抛出异常</li>
     *     <li>子方法1：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法2：使用{@link Propagation#REQUIRED}</li>
     * </ul>
     */
    void requiredEx_required_required();
    
    /**
     * 子方法1回滚，子方法2回滚（主方法存在事务，子方法加入该事务中）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法1：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法2：使用{@link Propagation#REQUIRED}，抛出异常</li>
     * </ul>
     */
    void required_required_requiredEx();

    /**
     * 子方法1回滚，子方法2回滚（虽然子方法2捕获了异常，但三个方法共用同一个事务，即使主方法没有感知到异常，子方法1也会随着子方法2的回滚而回滚）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法1：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法2：使用{@link Propagation#REQUIRED}，捕获异常</li>
     * </ul>
     */
    void required_required_requiredCatch();

    /**
     * 子方法1成功，子方法2成功（子方法事务独立，主方法无事务不受影响）
     * <ul>
     *     <li>主方法：不使用事务，抛出异常</li>
     *     <li>子方法1：使用{@link Propagation#REQUIRES_NEW}</li>
     *     <li>子方法2：使用{@link Propagation#REQUIRES_NEW}</li>
     * </ul>
     */
    void noEx_new_new();

    /**
     * 子方法1成功，子方法2回滚（子方法事务独立，主方法无事务不受影响）
     * <ul>
     *     <li>主方法：不使用事务</li>
     *     <li>子方法1：使用{@link Propagation#REQUIRES_NEW}</li>
     *     <li>子方法2：使用{@link Propagation#REQUIRES_NEW}，抛出异常</li>
     * </ul>
     */
    void no_new_newEx();
    
    /**
     * 子方法1成功，子方法2成功（子方法都是独立的事务，主方法的事务不会影响子方法的事务）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}，抛出异常</li>
     *     <li>子方法1：使用{@link Propagation#REQUIRES_NEW}</li>
     *     <li>子方法2：使用{@link Propagation#REQUIRES_NEW}</li>
     * </ul>
     */
    void requiredEx_new_new();
    
    /**
     * 子方法1成功，子方法2回滚（子方法事务独立，不受外部影响）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法1：使用{@link Propagation#REQUIRES_NEW}</li>
     *     <li>子方法2：使用{@link Propagation#REQUIRES_NEW}，抛出异常</li>
     * </ul>
     */
    void required_new_newEx();
    
    /**
     * 子方法1成功，子方法2回滚（子方法事务独立，不受外部影响）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法1：使用{@link Propagation#REQUIRES_NEW}</li>
     *     <li>子方法2：使用{@link Propagation#REQUIRES_NEW}，捕获异常</li>
     * </ul>
     */
    void required_new_newCatch();

    /**
     * 子方法1成功，子方法2成功（主方法无事务，嵌套事务不成立，执行与{@link Propagation#REQUIRED}类似的操作）
     * <ul>
     *     <li>主方法：不使用事务，抛出异常</li>
     *     <li>子方法1：使用{@link Propagation#NESTED}</li>
     *     <li>子方法2：使用{@link Propagation#NESTED}</li>
     * </ul>
     */
    void noEx_nested_nested();

    /**
     * 子方法1成功，子方法2回滚（主方法无事务，嵌套事务不成立，执行与{@link Propagation#REQUIRED}类似的操作）
     * <ul>
     *     <li>主方法：不使用事务</li>
     *     <li>子方法1：使用{@link Propagation#NESTED}</li>
     *     <li>子方法2：使用{@link Propagation#NESTED}，抛出异常</li>
     * </ul>
     */
    void no_nested_nestedEx();
    
    /**
     * 子方法1回滚，子方法2回滚（嵌套事务，子方法事务为主方法事务的子事务，主事务回滚会使所有子事务同步回滚）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}，抛出异常</li>
     *     <li>子方法1：使用{@link Propagation#NESTED}</li>
     *     <li>子方法2：使用{@link Propagation#NESTED}</li>
     * </ul>
     */
    void requiredEx_nested_nested();
    
    /**
     * 子方法1回滚，子方法2回滚（嵌套事务，子方法的异常被主方法感知，故主事务回滚，触发子事务同步回滚）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法1：使用{@link Propagation#NESTED}</li>
     *     <li>子方法2：使用{@link Propagation#NESTED}，抛出异常</li>
     * </ul>
     */
    void required_nested_nestedEx();
    
    /**
     * 子方法1成功，子方法2回滚（嵌套事务，子方法2异常被拦截，主方法未感知到异常，故子方法2自行回滚）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法1：使用{@link Propagation#NESTED}</li>
     *     <li>子方法2：使用{@link Propagation#NESTED}，捕获异常</li>
     * </ul>
     */
    void required_nested_nestedCatch();

    /**
     * 子方法1成功，子方法2成功（当前不存在事务，以非事务方式执行）
     * <ul>
     *     <li>主方法：不使用事务，抛出异常</li>
     *     <li>子方法1：使用{@link Propagation#SUPPORTS}</li>
     *     <li>子方法2：使用{@link Propagation#SUPPORTS}</li>
     * </ul>
     */
    void noEx_supports_supports();

    /**
     * 子方法1成功，子方法2成功（当前不存在事务，以非事务方式执行）
     * <ul>
     *     <li>主方法：不使用事务</li>
     *     <li>子方法1：使用{@link Propagation#SUPPORTS}</li>
     *     <li>子方法2：使用{@link Propagation#SUPPORTS}，抛出异常</li>
     * </ul>
     */
    void no_supports_supportsEx();
    
    /**
     * 子方法1回滚，子方法2回滚（支持当前事务，以当前事务规则执行）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}，抛出异常</li>
     *     <li>子方法1：使用{@link Propagation#SUPPORTS}</li>
     *     <li>子方法2：使用{@link Propagation#SUPPORTS}</li>
     * </ul>
     */
    void requiredEx_supports_supports();
    
    /**
     * 子方法1回滚，子方法2回滚（支持当前事务，以当前事务规则执行）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法1：使用{@link Propagation#SUPPORTS}</li>
     *     <li>子方法2：使用{@link Propagation#SUPPORTS}，抛出异常</li>
     * </ul>
     */
    void required_supports_supportsEx();
    
    /**
     * 子方法1回滚，子方法2回滚（支持当前事务，以当前事务规则执行）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法1：使用{@link Propagation#SUPPORTS}</li>
     *     <li>子方法2：使用{@link Propagation#SUPPORTS}，捕获异常</li>
     * </ul>
     */
    void required_supports_supportsCatch();

    /**
     * 方法抛出异常，不会执行（主方法无事务，直接抛出异常）
     * <ul>
     *     <li>主方法：不使用事务</li>
     *     <li>子方法1：使用{@link Propagation#MANDATORY}</li>
     *     <li>子方法2：使用{@link Propagation#MANDATORY}</li>
     * </ul>
     */
    void no_mandatory_mandatory();

    /**
     * 子方法1回滚，子方法2回滚（使用主方法的事务）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}，抛出异常</li>
     *     <li>子方法1：使用{@link Propagation#MANDATORY}</li>
     *     <li>子方法2：使用{@link Propagation#MANDATORY}</li>
     * </ul>
     */
    void requiredEx_mandatory_mandatory();

    /**
     * 子方法1回滚，子方法2回滚（使用主方法的事务）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法1：使用{@link Propagation#MANDATORY}</li>
     *     <li>子方法2：使用{@link Propagation#MANDATORY}，抛出异常</li>
     * </ul>
     */
    void required_mandatory_mandatoryEx();

    /**
     * 子方法1回滚，子方法2回滚（使用主方法的事务）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法1：使用{@link Propagation#MANDATORY}</li>
     *     <li>子方法2：使用{@link Propagation#MANDATORY}，捕获异常</li>
     * </ul>
     */
    void required_mandatory_mandatoryCatch();
    
    /**
     * 子方法1成功，子方法2成功（主方法有事务，挂起该事务，以非事务方式执行）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}，抛出异常</li>
     *     <li>子方法1：使用{@link Propagation#NOT_SUPPORTED}</li>
     *     <li>子方法2：使用{@link Propagation#NOT_SUPPORTED}</li>
     * </ul>
     */
    void requiredEx_not_not();
    
    /**
     * 子方法1成功，子方法2成功（主方法有事务，挂起该事务，以非事务方式执行）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法1：使用{@link Propagation#NOT_SUPPORTED}</li>
     *     <li>子方法2：使用{@link Propagation#NOT_SUPPORTED}，抛出异常</li>
     * </ul>
     */
    void required_not_notEx();
    
    /**
     * 子方法1成功，子方法2成功（主方法有事务，挂起该事务，以非事务方式执行）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}</li>
     *     <li>子方法1：使用{@link Propagation#NOT_SUPPORTED}</li>
     *     <li>子方法2：使用{@link Propagation#NOT_SUPPORTED}，捕获异常</li>
     * </ul>
     */
    void required_not_notCatch();

    /**
     * 子方法1成功，子方法2回滚（主方法有事务，子方法1挂起该事务，子方法2使用该事务，故回滚对子方法1不生效）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}，捕获异常</li>
     *     <li>子方法1：使用{@link Propagation#NOT_SUPPORTED}</li>
     *     <li>子方法2：使用{@link Propagation#REQUIRED}</li>
     * </ul>
     */
    void requiredEx_not_required();

    /**
     * 子方法1回滚，子方法2成功（主方法有事务，子方法1使用该事务，子方法2挂起该事务，故回滚对子方法2不生效）
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}，捕获异常</li>
     *     <li>子方法1：使用{@link Propagation#NOT_SUPPORTED}</li>
     *     <li>子方法2：使用{@link Propagation#REQUIRED}</li>
     * </ul>
     */
    void required_required_notEx();
    
    /**
     * 子方法1成功，子方法2成功（以非事务执行）
     * <ul>
     *     <li>主方法：不使用事务，抛出异常</li>
     *     <li>子方法1：使用{@link Propagation#NEVER}</li>
     *     <li>子方法2：使用{@link Propagation#NEVER}</li>
     * </ul>
     */
    void noEx_never_never();

    /**
     * 子方法1成功，子方法2成功（以非事务执行）
     * <ul>
     *     <li>主方法：不使用事务</li>
     *     <li>子方法1：使用{@link Propagation#NEVER}</li>
     *     <li>子方法2：使用{@link Propagation#NEVER}，抛出异常</li>
     * </ul>
     */
    void no_never_neverEx();
    
    /**
     * 存在事务，抛出异常，不会执行
     * <ul>
     *     <li>主方法：使用{@link Propagation#REQUIRED}，抛出异常</li>
     *     <li>子方法1：使用{@link Propagation#NEVER}</li>
     *     <li>子方法2：使用{@link Propagation#NEVER}</li>
     * </ul>
     */
    void required_never_never();

}
